﻿using System;
using System.ComponentModel.DataAnnotations.Schema;

using ApproveFlowEngine.Core.Base;
using ApproveFlowEngine.Enums.Core;

using Volo.Abp;

namespace ApproveFlowEngine.Core.Nodes
{
    public class WorkNodeSerial : WorkNodeComplex
    {
        #region Public Constructors

        public WorkNodeSerial(Guid id) : base( id)
        {
            NodeType = NodeType.Serial;
        }

        #endregion Public Constructors



        #region Protected Constructors

        protected WorkNodeSerial()
        {
            NodeType = NodeType.Serial;
        }

        #endregion Protected Constructors



        #region Public Properties

        [NotMapped]
        public WorkNode? Current { get; set; }

        public override ApproveNodeStatus Status
        {
            get
            {
                if (Children.Count == PassCount)
                {
                    return ApproveNodeStatus.Pass;
                }
                if (Children.Count == NoneCount)
                {
                    return ApproveNodeStatus.None;
                }
                if (RejectCount > 0)
                {
                    return ApproveNodeStatus.Reject;
                }
                return ApproveNodeStatus.Activity;
            }
        }

        #endregion Public Properties



        #region Public Methods

        public override bool ExecApprove(Guid nodeId, ApproveNodeStatus status)
        {
            if (nodeId == Id)
            {
                throw new BusinessException($"【{nodeId}】节点ID错误！");
            }
            if (Current is null)
            {
                return false;
            }
            var result = Current.Approve(nodeId, status);
            MoveNext();
            return result;
        }

        public override void Init()
        {
            Activity = true;
            Head?.Init();
        }

        public void MoveNext()
        {
            if (Current is null)
            {
                return;
            }
            if (Current.Status is ApproveNodeStatus.Pass)
            {
                if (Current.Next is not null)
                {
                    Current = Current.Next;
                    Current.Init();
                }
            }
        }

        #endregion Public Methods
    }
}